package com.lagou.guava.service;

import com.alibaba.fastjson.JSON;
import com.google.common.cache.LoadingCache;
import com.lagou.guava.entity.Position;
import com.lagou.guava.repository.PositionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author shenxiang
 * @date 2020/9/23 9:46
 * @description
 */
@Service
public class PositionService {

    @Autowired
    private PositionRepository positionRepository;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private LoadingCache<String,Object> guava;

    public Position getOneById(Long id) throws ExecutionException {
        String key = "position:id:"+id;
        Object guavaRow = guava.getIfPresent(key);
        if (!StringUtils.isEmpty(guavaRow)){
            return JSON.parseObject(guavaRow.toString(),Position.class);
        }
        Object row = redisTemplate.opsForValue().get(key);
        Position p = new Position();
        if (StringUtils.isEmpty(row)){
            Optional<Position> repositoryById = positionRepository.findById(id);
            p = repositoryById.orElse(null);
            if (p != null) {
                guava.put(key,JSON.toJSONString(p));
                redisTemplate.opsForValue().set(key, JSON.toJSONString(p), 3600, TimeUnit.SECONDS);
            }
        }else{
            // 重启后本地缓存失效,此时再将分布式缓存中的数据写一份到本地缓存，否则在分布式缓存失效前一直会走分布式缓存
            guava.put(key,row.toString());
            p = JSON.parseObject(row.toString(), Position.class);
        }
        return p;
    }

    public Position save(Position position){
        return positionRepository.save(position);
    }

    public void deleteById(Long id){
        positionRepository.deleteById(id);
    }

    public List<Position> getAll() throws ExecutionException {
        List<Position> list = new ArrayList<>();
        String key = "position:all:list";
        // 先从本地缓存中读取,如果有则直接返回
        Object guavaObj = guava.getIfPresent(key);
        if (!StringUtils.isEmpty(guavaObj)){
            return JSON.parseArray(guavaObj.toString(),Position.class);
        }
        // 再从分布式缓存中读取,有则返回
        Object o = redisTemplate.opsForValue().get(key);
        // 分布式缓存中也不存在,查DB
        if (StringUtils.isEmpty(o)){
            list = positionRepository.findAll();
            if (list.size() > 0){
                guava.put(key,JSON.toJSONString(list));
                redisTemplate.opsForValue().set(key,JSON.toJSONString(list),3600,TimeUnit.SECONDS);
            }
        }else{
            // 重启后本地缓存失效,此时再将分布式缓存中的数据写一份到本地缓存，否则在分布式缓存失效前一直会走分布式缓存
            guava.put(key,o.toString());
            list = JSON.parseArray(o.toString(),Position.class);
        }
        return list;
    }
}
